/*
 * $Id: QEADIFValue.h 77 2009-06-26 02:57:26Z jon@bway.net $
 * Chalk
 *
 * Created 5/11/09
 * Copyright Jon Gordon
 * 
 * Permission is hereby granted, free of charge, to any person obtaining 
 * a copy of this software and associated documentation files (the
 * "Software"), to deal in the Software without restriction, including 
 * without limitation the rights to use, copy, modify, merge, publish, 
 * distribute, sublicense, and/or sell copies of the Software, and to 
 * permit persons to whom the Software is furnished to do so, subject to 
 * the following conditions:
 * 
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 * 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 
 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */

#import <Foundation/Foundation.h>

#import "QEADIFInternal.h"


@class QEADIFLocation;


@interface QEADIFValue : NSObject <NSCopying> {
@private
    QEADIFType adifType;
    id value;
    NSString *stringValue;
    id enumerationSpec;
}

@property (readonly, nonatomic) QEADIFType adifType;
@property (readonly, nonatomic) id value;
@property (readonly, nonatomic) NSString *stringValue;
@property (readonly, nonatomic) id enumerationSpec;

#pragma mark FIELD INFORMATION METHODS
+ (BOOL)isHeaderOnlyField:(NSString *)fieldName;
+ (BOOL)isEnumerationField:(NSString *)fieldName;
+ (id)enumerationSpecForFieldName:(NSString *)fieldName;
+ (QEADIFType)typeForFieldName:(NSString *)fieldName;

#pragma mark DATA TYPE MAPPING METHODS
+ (unichar)adifType2TypeCode:(QEADIFType)adifType;
+ (QEADIFType)adifTypeCode2Type:(unichar)adifTypeCode;
+ (NSString *)adifType2TypeName:(QEADIFType)adifType;
+ (QEADIFType)adifTypeName2Type:(NSString *)typeName;

#pragma mark CLASS VALIDATION METHODS
/*
 * ADIF supports 11 data types: AwardList, Boolean, Digit, Number,
 * Character, Date, Time, String, MultilineString, Enumeration,
 * and Location.  Each of the following class methods takes a reference
 * to an NSString and indicates the the object of the reference is
 * a valid representation of a value of the indicated type or can
 * be converted to one.
 *
 * If the object of the reference is *not* a valid value, but can
 * be converted to one, the original source is replaced with a
 * a converted, correct value, and the method returns YES.
 */
+ (BOOL)isValidAwardListSrc:(NSString **)src;
+ (BOOL)isValidAwardListSrc:(NSString **)src error:(NSError **)outError;
+ (BOOL)isValidBooleanSrc:(NSString **)src;
+ (BOOL)isValidBooleanSrc:(NSString **)src error:(NSError **)outError;
+ (BOOL)isValidDigitSrc:(NSString **)src;
+ (BOOL)isValidDigitSrc:(NSString **)src error:(NSError **)outError;
+ (BOOL)isValidNumberSrc:(NSString **)src;
+ (BOOL)isValidNumberSrc:(NSString **)src error:(NSError **)outError;
+ (BOOL)isValidCharacterSrc:(NSString **)src;
+ (BOOL)isValidCharacterSrc:(NSString **)src error:(NSError **)outError;
+ (BOOL)isValidDateSrc:(NSString **)src;
+ (BOOL)isValidDateSrc:(NSString **)src error:(NSError **)outError;
+ (BOOL)isValidTimeSrc:(NSString **)src;
+ (BOOL)isValidTimeSrc:(NSString **)src error:(NSError **)outError;
+ (BOOL)isValidStringSrc:(NSString **)src;
+ (BOOL)isValidStringSrc:(NSString **)src error:(NSError **)outError;
+ (BOOL)isValidMultilineStringSrc:(NSString **)src;
+ (BOOL)isValidMultilineStringSrc:(NSString **)src error:(NSError **)outError;
+ (BOOL)isValidLocationSrc:(NSString **)src;
+ (BOOL)isValidLocationSrc:(NSString **)src error:(NSError **)outError;
+ (BOOL)isValidValueSrc:(NSString **)src fromEnumeration:(id)enumSpec;
+ (BOOL)isValidValueSrc:(NSString **)src fromEnumeration:(id)enumSpec error:(NSError **)outError;

#pragma mark VALUE CREATION METHODS
+ (QEADIFValue *)awardListFromString:(NSString *)src;
+ (QEADIFValue *)awardListFromArray:(NSArray *)list;

+ (QEADIFValue *)booleanFromString:(NSString *)src;
+ (QEADIFValue *)booleanFromBool:(BOOL)b;

+ (QEADIFValue *)digitFromString:(NSString *)src;
+ (QEADIFValue *)digitFromUint:(unsigned int)digit;
+ (QEADIFValue *)digitFromChar:(unichar)digit;

+ (QEADIFValue *)numberFromString:(NSString *)src;
+ (QEADIFValue *)numberFromDecimalNumber:(NSDecimalNumber *)number;

+ (QEADIFValue *)characterFromString:(NSString *)src;
+ (QEADIFValue *)characterFromChar:(unichar)c;

+ (QEADIFValue *)dateFromString:(NSString *)src;
+ (QEADIFValue *)dateFromComponents:(NSDateComponents *)comp;

+ (QEADIFValue *)timeFromString:(NSString *)src;
+ (QEADIFValue *)timeFromComponents:(NSDateComponents *)comp;

+ (QEADIFValue *)stringFromString:(NSString *)src;

+ (QEADIFValue *)multilineStringFromString:(NSString *)src;

+ (QEADIFValue *)locationFromString:(NSString *)src;
+ (QEADIFValue *)locationFromLocation:(QEADIFLocation *)l;

+ (QEADIFValue *)valueFromString:(NSString *)src fromEnumeration:(id)enumSpec;

#pragma mark PROPERTIES
- (unichar)typeCode;    // calculated from adifType property

- (NSInteger)integerValue;
- (NSDecimalNumber *)decimalValue;
- (NSDateComponents *)componentValue;
- (BOOL)boolValue;
- (QEADIFLocation *)locationValue;
@end
